{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5a172e1e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "import torchvision.transforms as transforms\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d5d2bc77",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using PyTorch version: 1.13.1+cu117  Device: cuda\n",
      "Files already downloaded and verified\n",
      "Files already downloaded and verified\n"
     ]
    }
   ],
   "source": [
    "if torch.cuda.is_available():\n",
    "    device = torch.device('cuda')\n",
    "else:\n",
    "    device = torch.device('cpu')\n",
    "    \n",
    "print('Using PyTorch version:', torch.__version__, ' Device:', device)\n",
    "\n",
    "\n",
    "#1.load data\n",
    "#TODO 进行数据增强跑起来试试看！！！\n",
    "transform = transforms.Compose(\n",
    "    [transforms.ToTensor(),\n",
    "     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n",
    "\n",
    "batch_size = 128\n",
    "\n",
    "#这是已经划分好训练和测试数据集了的\n",
    "trainset = torchvision.datasets.CIFAR100(root='./cifar-100-python', train=True,\n",
    "                                        download=True, transform=transform)\n",
    "trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,\n",
    "                                          shuffle=True, num_workers=2)\n",
    "\n",
    "testset = torchvision.datasets.CIFAR100(root='./cifar-100-python', train=False,\n",
    "                                       download=True, transform=transform)\n",
    "testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,\n",
    "                                         shuffle=False, num_workers=2)\n",
    "\n",
    "classes = {19: 'cattle', 29: 'dinosaur', 0: 'apple', 11: 'boy', 1: 'aquarium_fish', 86: 'telephone',\n",
    "           90: 'train', 28: 'cup', 23: 'cloud', 31: 'elephant', 39: 'keyboard', 96: 'willow_tree', \n",
    "           82: 'sunflower', 17: 'castle', 71: 'sea', 8: 'bicycle', 97: 'wolf', 80: 'squirrel', \n",
    "           74: 'shrew', 59: 'pine_tree', 70: 'rose', 87: 'television', 84: 'table', 64: 'possum', \n",
    "           52: 'oak_tree', 42: 'leopard', 47: 'maple_tree', 65: 'rabbit', 21: 'chimpanzee', \n",
    "           22: 'clock', 81: 'streetcar', 24: 'cockroach', 78: 'snake', 45: 'lobster', 49: 'mountain', \n",
    "           56: 'palm_tree', 76: 'skyscraper', 89: 'tractor', 73: 'shark', 14: 'butterfly', 9: 'bottle', \n",
    "           6: 'bee', 20: 'chair', 98: 'woman', 36: 'hamster', 55: 'otter', 72: 'seal', 43: 'lion', 51: 'mushroom', \n",
    "           35: 'girl', 83: 'sweet_pepper', 33: 'forest', 27: 'crocodile', 53: 'orange', 92: 'tulip', 50: 'mouse', \n",
    "           15: 'camel', 18: 'caterpillar', 46: 'man', 75: 'skunk', 38: 'kangaroo', 66: 'raccoon', 77: 'snail', \n",
    "           69: 'rocket', 95: 'whale', 99: 'worm', 93: 'turtle', 4: 'beaver', 61: 'plate', 94: 'wardrobe', 68: 'road', \n",
    "           34: 'fox', 32: 'flatfish', 88: 'tiger', 67: 'ray', 30: 'dolphin', 62: 'poppy', 63: 'porcupine', 40: 'lamp', \n",
    "           26: 'crab', 48: 'motorcycle', 79: 'spider', 85: 'tank', 54: 'orchid', 44: 'lizard', 7: 'beetle', 12: 'bridge', \n",
    "           2: 'baby', 41: 'lawn_mower', 37: 'house', 13: 'bus', 25: 'couch', 10: 'bowl', 57: 'pear', 5: 'bed', \n",
    "           60: 'plain', 91: 'trout', 3: 'bear', 58: 'pickup_truck', 16: 'can'}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a687d74c",
   "metadata": {},
   "source": [
    "## 2. Define a ResNet\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "242a1ec2",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "454c52f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# from https://github.com/bubbliiiing/yolov4-tiny-pytorch\n",
    "class CA_Block(nn.Module):\n",
    "    def __init__(self, channel, reduction=16):\n",
    "        super(CA_Block, self).__init__()\n",
    "        \n",
    "        self.conv_1x1 = nn.Conv2d(in_channels=channel, out_channels=channel//reduction, kernel_size=1, stride=1, bias=False)\n",
    " \n",
    "        self.relu   = nn.ReLU()\n",
    "        self.bn     = nn.BatchNorm2d(channel//reduction)\n",
    " \n",
    "        self.F_h = nn.Conv2d(in_channels=channel//reduction, out_channels=channel, kernel_size=1, stride=1, bias=False)\n",
    "        self.F_w = nn.Conv2d(in_channels=channel//reduction, out_channels=channel, kernel_size=1, stride=1, bias=False)\n",
    " \n",
    "        self.sigmoid_h = nn.Sigmoid()\n",
    "        self.sigmoid_w = nn.Sigmoid()\n",
    " \n",
    "    def forward(self, x):\n",
    "        _, _, h, w = x.size()\n",
    "        \n",
    "        x_h = torch.mean(x, dim = 3, keepdim = True).permute(0, 1, 3, 2)\n",
    "        x_w = torch.mean(x, dim = 2, keepdim = True)\n",
    " \n",
    "        x_cat_conv_relu = self.relu(self.bn(self.conv_1x1(torch.cat((x_h, x_w), 3))))\n",
    " \n",
    "        x_cat_conv_split_h, x_cat_conv_split_w = x_cat_conv_relu.split([h, w], 3)\n",
    " \n",
    "        s_h = self.sigmoid_h(self.F_h(x_cat_conv_split_h.permute(0, 1, 3, 2)))\n",
    "        s_w = self.sigmoid_w(self.F_w(x_cat_conv_split_w))\n",
    " \n",
    "        out = x * s_h.expand_as(x) * s_w.expand_as(x)\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d6435cb5",
   "metadata": {},
   "outputs": [],
   "source": [
    "#残差块\n",
    "#TODO 看具体残差块含义\n",
    "class BasicBlock(nn.Module):\n",
    "    expansion = 1\n",
    "\n",
    "    def __init__(self, in_channel, out_channel, stride=1):\n",
    "        super(BasicBlock, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(in_channel, out_channel, kernel_size=3,\n",
    "                               stride=stride, padding=1, bias=False)\n",
    "        self.bn1 = nn.BatchNorm2d(out_channel)\n",
    "        self.conv2 = nn.Conv2d(out_channel, out_channel, kernel_size=3,\n",
    "                               stride=1, padding=1, bias=False)\n",
    "        self.bn2 = nn.BatchNorm2d(out_channel)\n",
    "        self.shortcut = nn.Sequential()\n",
    "\n",
    "        if stride != 1 or in_channel != self.expansion * out_channel:\n",
    "            self.shortcut = nn.Sequential(\n",
    "                nn.Conv2d(in_channel, self.expansion * out_channel,\n",
    "                          kernel_size=1, stride=stride, bias=False),\n",
    "                nn.BatchNorm2d(self.expansion * out_channel)\n",
    "            )\n",
    "\n",
    "    def forward(self, x):\n",
    "        out = F.relu(self.bn1(self.conv1(x)))\n",
    "        out = self.bn2(self.conv2(out))\n",
    "        out += self.shortcut(x)\n",
    "        out = F.relu(out)\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "6b30d168",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Net(\n",
      "  (conv1): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "  (layer1): Sequential(\n",
      "    (0): BasicBlock(\n",
      "      (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (shortcut): Sequential()\n",
      "    )\n",
      "    (1): BasicBlock(\n",
      "      (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (shortcut): Sequential()\n",
      "    )\n",
      "  )\n",
      "  (layer2): Sequential(\n",
      "    (0): BasicBlock(\n",
      "      (conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (shortcut): Sequential(\n",
      "        (0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)\n",
      "        (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      )\n",
      "    )\n",
      "    (1): BasicBlock(\n",
      "      (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (shortcut): Sequential()\n",
      "    )\n",
      "  )\n",
      "  (layer3): Sequential(\n",
      "    (0): BasicBlock(\n",
      "      (conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (shortcut): Sequential(\n",
      "        (0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)\n",
      "        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      )\n",
      "    )\n",
      "    (1): BasicBlock(\n",
      "      (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (shortcut): Sequential()\n",
      "    )\n",
      "  )\n",
      "  (layer4): Sequential(\n",
      "    (0): BasicBlock(\n",
      "      (conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (shortcut): Sequential(\n",
      "        (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)\n",
      "        (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      )\n",
      "    )\n",
      "    (1): BasicBlock(\n",
      "      (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (shortcut): Sequential()\n",
      "    )\n",
      "  )\n",
      "  (CA): Sequential(\n",
      "    (0): CA_Block(\n",
      "      (conv_1x1): Conv2d(512, 1, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (relu): ReLU()\n",
      "      (bn): BatchNorm2d(1, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (F_h): Conv2d(1, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (F_w): Conv2d(1, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (sigmoid_h): Sigmoid()\n",
      "      (sigmoid_w): Sigmoid()\n",
      "    )\n",
      "  )\n",
      "  (linear): Linear(in_features=512, out_features=100, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "class Net(nn.Module):\n",
    "    def __init__(self, block, num_blocks, num_classes=100):\n",
    "        super(Net, self).__init__()\n",
    "        self.in_channel = 64\n",
    "\n",
    "        self.conv1 = nn.Conv2d(3, 64, kernel_size=3,\n",
    "                               stride=1, padding=1, bias=False)\n",
    "        self.bn1 = nn.BatchNorm2d(64)\n",
    "\n",
    "        self.layer1 = self.make_layer(block, 64, num_blocks[0], stride=1)\n",
    "        self.layer2 = self.make_layer(block, 128, num_blocks[1], stride=2)\n",
    "        self.layer3 = self.make_layer(block, 256, num_blocks[2], stride=2)\n",
    "        self.layer4 = self.make_layer(block, 512, num_blocks[3], stride=2)\n",
    "        self.CA = self.make_CA(512)\n",
    "        self.linear = nn.Linear(512 * block.expansion, num_classes)\n",
    "\n",
    "    def make_layer(self, block, out_channel, num_blocks, stride):\n",
    "        strides = [stride] + (num_blocks - 1) * [1]\n",
    "        layers = []\n",
    "        for stride in strides:\n",
    "            layers.append(block(self.in_channel, out_channel, stride))\n",
    "            self.in_channel = out_channel * block.expansion\n",
    "        return nn.Sequential(*layers)\n",
    "    \n",
    "    def make_CA(self, out_channel):\n",
    "        layers = []\n",
    "        layers.append(CA_Block(self.in_channel, out_channel))\n",
    "        self.in_channel = out_channel * 1\n",
    "        return nn.Sequential(*layers)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        out = F.relu(self.bn1(self.conv1(x)))\n",
    "        out = self.layer1(out)\n",
    "        out = self.layer2(out)\n",
    "        out = self.layer3(out)\n",
    "        out = self.layer4(out)\n",
    "        out = F.avg_pool2d(out, 4)\n",
    "        out = out.view(out.size(0), -1)\n",
    "        out = self.linear(out)\n",
    "        return out\n",
    "\n",
    "#超参都可以改！！！\n",
    "def ResNet():\n",
    "    return Net(BasicBlock, [2, 2, 2,2])#4个残差块？？？\n",
    "\n",
    "\n",
    "net = ResNet().to(device)\n",
    "print(net)\n",
    "\n",
    "#一些超参\n",
    "import torch.optim as optim\n",
    "\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "e493e029",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "50000\n"
     ]
    }
   ],
   "source": [
    "total = 0\n",
    "for data, target in trainloader:\n",
    "    target = target.to(device)\n",
    "    total += target.size(0)\n",
    "print(total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "a9329e77",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1,    50] loss: 0.821\n",
      "[1,   100] loss: 0.829\n",
      "[1,   150] loss: 0.930\n",
      "[1,   200] loss: 0.935\n",
      "[1,   250] loss: 0.981\n",
      "[1,   300] loss: 0.942\n",
      "[1,   350] loss: 0.964\n",
      "\n",
      "Validation set: Average loss: 0.0204, Accuracy: 4199/10000 (42%)\n",
      "\n",
      "[2,    50] loss: 0.585\n",
      "[2,   100] loss: 0.638\n",
      "[2,   150] loss: 0.689\n",
      "[2,   200] loss: 0.694\n",
      "[2,   250] loss: 0.727\n",
      "[2,   300] loss: 0.780\n",
      "[2,   350] loss: 0.770\n",
      "\n",
      "Validation set: Average loss: 0.0211, Accuracy: 4333/10000 (43%)\n",
      "\n",
      "[3,    50] loss: 0.414\n",
      "[3,   100] loss: 0.451\n",
      "[3,   150] loss: 0.518\n",
      "[3,   200] loss: 0.497\n",
      "[3,   250] loss: 0.562\n",
      "[3,   300] loss: 0.542\n",
      "[3,   350] loss: 0.598\n",
      "\n",
      "Validation set: Average loss: 0.0233, Accuracy: 4322/10000 (43%)\n",
      "\n",
      "[4,    50] loss: 0.325\n",
      "[4,   100] loss: 0.342\n",
      "[4,   150] loss: 0.375\n",
      "[4,   200] loss: 0.339\n",
      "[4,   250] loss: 0.409\n",
      "[4,   300] loss: 0.423\n",
      "[4,   350] loss: 0.475\n",
      "\n",
      "Validation set: Average loss: 0.0262, Accuracy: 4388/10000 (44%)\n",
      "\n",
      "[5,    50] loss: 0.268\n",
      "[5,   100] loss: 0.258\n",
      "[5,   150] loss: 0.285\n",
      "[5,   200] loss: 0.308\n",
      "[5,   250] loss: 0.315\n",
      "[5,   300] loss: 0.346\n",
      "[5,   350] loss: 0.381\n",
      "\n",
      "Validation set: Average loss: 0.0260, Accuracy: 4404/10000 (44%)\n",
      "\n",
      "[6,    50] loss: 0.185\n",
      "[6,   100] loss: 0.226\n",
      "[6,   150] loss: 0.207\n",
      "[6,   200] loss: 0.213\n",
      "[6,   250] loss: 0.226\n",
      "[6,   300] loss: 0.272\n",
      "[6,   350] loss: 0.274\n",
      "\n",
      "Validation set: Average loss: 0.0281, Accuracy: 4245/10000 (42%)\n",
      "\n",
      "[7,    50] loss: 0.170\n",
      "[7,   100] loss: 0.169\n",
      "[7,   150] loss: 0.204\n",
      "[7,   200] loss: 0.219\n",
      "[7,   250] loss: 0.207\n",
      "[7,   300] loss: 0.180\n",
      "[7,   350] loss: 0.229\n",
      "\n",
      "Validation set: Average loss: 0.0276, Accuracy: 4452/10000 (45%)\n",
      "\n",
      "[8,    50] loss: 0.131\n",
      "[8,   100] loss: 0.143\n",
      "[8,   150] loss: 0.129\n",
      "[8,   200] loss: 0.178\n",
      "[8,   250] loss: 0.195\n",
      "[8,   300] loss: 0.141\n",
      "[8,   350] loss: 0.194\n",
      "\n",
      "Validation set: Average loss: 0.0272, Accuracy: 4458/10000 (45%)\n",
      "\n",
      "[9,    50] loss: 0.103\n",
      "[9,   100] loss: 0.086\n",
      "[9,   150] loss: 0.111\n",
      "[9,   200] loss: 0.130\n",
      "[9,   250] loss: 0.106\n",
      "[9,   300] loss: 0.153\n",
      "[9,   350] loss: 0.124\n",
      "\n",
      "Validation set: Average loss: 0.0301, Accuracy: 4522/10000 (45%)\n",
      "\n",
      "[10,    50] loss: 0.096\n",
      "[10,   100] loss: 0.090\n",
      "[10,   150] loss: 0.102\n",
      "[10,   200] loss: 0.112\n",
      "[10,   250] loss: 0.100\n",
      "[10,   300] loss: 0.134\n",
      "[10,   350] loss: 0.134\n",
      "\n",
      "Validation set: Average loss: 0.0316, Accuracy: 4431/10000 (44%)\n",
      "\n",
      "[11,    50] loss: 0.098\n",
      "[11,   100] loss: 0.057\n",
      "[11,   150] loss: 0.067\n",
      "[11,   200] loss: 0.087\n",
      "[11,   250] loss: 0.133\n",
      "[11,   300] loss: 0.107\n",
      "[11,   350] loss: 0.076\n",
      "\n",
      "Validation set: Average loss: 0.0318, Accuracy: 4159/10000 (42%)\n",
      "\n",
      "[12,    50] loss: 0.092\n",
      "[12,   100] loss: 0.066\n",
      "[12,   150] loss: 0.091\n",
      "[12,   200] loss: 0.078\n",
      "[12,   250] loss: 0.102\n",
      "[12,   300] loss: 0.073\n",
      "[12,   350] loss: 0.084\n",
      "\n",
      "Validation set: Average loss: 0.0333, Accuracy: 4377/10000 (44%)\n",
      "\n",
      "[13,    50] loss: 0.074\n",
      "[13,   100] loss: 0.060\n",
      "[13,   150] loss: 0.059\n",
      "[13,   200] loss: 0.098\n",
      "[13,   250] loss: 0.098\n",
      "[13,   300] loss: 0.073\n",
      "[13,   350] loss: 0.087\n",
      "\n",
      "Validation set: Average loss: 0.0351, Accuracy: 4455/10000 (45%)\n",
      "\n",
      "[14,    50] loss: 0.048\n",
      "[14,   100] loss: 0.068\n",
      "[14,   150] loss: 0.089\n",
      "[14,   200] loss: 0.079\n",
      "[14,   250] loss: 0.079\n",
      "[14,   300] loss: 0.084\n",
      "[14,   350] loss: 0.080\n",
      "\n",
      "Validation set: Average loss: 0.0320, Accuracy: 4441/10000 (44%)\n",
      "\n",
      "[15,    50] loss: 0.062\n",
      "[15,   100] loss: 0.065\n",
      "[15,   150] loss: 0.059\n",
      "[15,   200] loss: 0.053\n",
      "[15,   250] loss: 0.040\n",
      "[15,   300] loss: 0.057\n",
      "[15,   350] loss: 0.080\n",
      "\n",
      "Validation set: Average loss: 0.0334, Accuracy: 4436/10000 (44%)\n",
      "\n",
      "[16,    50] loss: 0.062\n",
      "[16,   100] loss: 0.040\n",
      "[16,   150] loss: 0.065\n",
      "[16,   200] loss: 0.050\n",
      "[16,   250] loss: 0.049\n",
      "[16,   300] loss: 0.048\n",
      "[16,   350] loss: 0.057\n",
      "\n",
      "Validation set: Average loss: 0.0357, Accuracy: 4407/10000 (44%)\n",
      "\n",
      "[17,    50] loss: 0.054\n",
      "[17,   100] loss: 0.035\n",
      "[17,   150] loss: 0.036\n",
      "[17,   200] loss: 0.058\n",
      "[17,   250] loss: 0.045\n",
      "[17,   300] loss: 0.045\n",
      "[17,   350] loss: 0.056\n",
      "\n",
      "Validation set: Average loss: 0.0347, Accuracy: 4443/10000 (44%)\n",
      "\n",
      "[18,    50] loss: 0.044\n",
      "[18,   100] loss: 0.041\n",
      "[18,   150] loss: 0.025\n",
      "[18,   200] loss: 0.034\n",
      "[18,   250] loss: 0.034\n",
      "[18,   300] loss: 0.040\n",
      "[18,   350] loss: 0.053\n",
      "\n",
      "Validation set: Average loss: 0.0363, Accuracy: 4439/10000 (44%)\n",
      "\n",
      "[19,    50] loss: 0.047\n",
      "[19,   100] loss: 0.037\n",
      "[19,   150] loss: 0.049\n",
      "[19,   200] loss: 0.047\n",
      "[19,   250] loss: 0.027\n",
      "[19,   300] loss: 0.032\n",
      "[19,   350] loss: 0.030\n",
      "\n",
      "Validation set: Average loss: 0.0352, Accuracy: 4539/10000 (45%)\n",
      "\n",
      "[20,    50] loss: 0.040\n",
      "[20,   100] loss: 0.031\n",
      "[20,   150] loss: 0.024\n",
      "[20,   200] loss: 0.034\n",
      "[20,   250] loss: 0.026\n",
      "[20,   300] loss: 0.041\n",
      "[20,   350] loss: 0.034\n",
      "\n",
      "Validation set: Average loss: 0.0335, Accuracy: 4631/10000 (46%)\n",
      "\n",
      "Training Finished\n"
     ]
    }
   ],
   "source": [
    "import torch.optim as optim\n",
    "\n",
    "#注意注意注意： 每次运行这里时 先把前面的above都运行一遍！！！--》即使值改动了epoch 前面的也得执行一遍！！！\n",
    "def validate(loss_vector, accuracy_vector):\n",
    "    net.eval()\n",
    "    total = 0\n",
    "    val_loss, correct = 0, 0\n",
    "    for data, target in testloader:\n",
    "        data = data.to(device)\n",
    "        target = target.to(device)\n",
    "        output = net(data)\n",
    "        val_loss += criterion(output, target).data.item()\n",
    "        _, predicted = torch.max(output.data, 1)\n",
    "        correct += (predicted == target).sum().item()\n",
    "        total += target.size(0)#total就是一个 总数...\n",
    "\n",
    "    val_loss /= total\n",
    "    loss_vector.append(val_loss)\n",
    "\n",
    "    accuracy = 100 * correct / total\n",
    "    accuracy_vector.append(accuracy)\n",
    "\n",
    "    print('\\nValidation set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n",
    "        val_loss, correct, total, accuracy))\n",
    "       \n",
    "#开始训练 \n",
    "lossv, accv = [], []\n",
    "\n",
    "epochs = 20#可调整--这里可以变成train函数\n",
    "#train\n",
    "for epoch in range(epochs):  # loop over the dataset multiple times\n",
    "    \n",
    "\n",
    "    running_loss = 0.0\n",
    "    for i, data in enumerate(trainloader, 0):\n",
    "        # get the inputs; data is a list of [inputs, labels]\n",
    "        inputs, labels = data\n",
    "        inputs = inputs.to(device)\n",
    "        labels = labels.to(device)\n",
    "\n",
    "        # zero the parameter gradients\n",
    "        optimizer.zero_grad()\n",
    "\n",
    "        # forward + backward + optimize\n",
    "        outputs = net(inputs)\n",
    "        loss = criterion(outputs, labels)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "        # print statistics\n",
    "        running_loss += loss.item()\n",
    "        if i % 50 == 49:    # print every 50 mini-batches\n",
    "            print(f'[{epoch+1}, {i+1:5d}] loss: {running_loss / 50:.3f}')\n",
    "            running_loss = 0.0\n",
    "    validate(lossv, accv)\n",
    "print('Training Finished')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ecf62cce",
   "metadata": {},
   "source": [
    "Let’s quickly save our trained model:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "9d94a16d",
   "metadata": {},
   "outputs": [],
   "source": [
    "PATH = './cifar_net.pth'\n",
    "torch.save(net.state_dict(), PATH)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "4c60ea6a",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'validation accuracy,epoch=5')"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 500x300 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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eYVVq1bxt7/9jdGjR9OjRw9yc3NJSEhgxYoVpKSklLrEIygoiD59+jBx4kSMRiNz5syhefPmpQ6bfvDBBwwfPpywsDDGjh1rvtTB3d291LWgVflOLFGdc36///47jz76KI8++ihBQUFcvnyZmJgYtm/fzvjx47n11lstWp+4DisMshF1wIYNGxSgNBqNOn36dJn5Z86cUffdd59q2rSpcnd3Vw8++KB59NzVlxFUZbSnUkqdPHlS3XvvvcrJyUm1aNFCTZ48Wa1bt67MqMTDhw+rwYMHKxcXF9WiRQs1btw49ccff5QZKl9UVKSee+455enpqTQaTamRn9fWqFTJcPvw8HDl4uKinJyc1MCBA9WOHTtKtbmyLdcOdy9v9GR5qtpnV/ojMjJSeXp6Kq1Wq9q2bauioqJKjcbMzMxUkyZNUi1btlT29vaqVatWatSoUerChQvmNklJSWrw4MFKq9Uqb29v9frrr5u/22tHe3bu3Lncurdv36569eqlHB0dla+vr5o6dapav359udu8bds2NWTIEOXq6qqcnZ1VSEiI+uSTT8qsMy0tTdna2qr27duX+5k//fRTuZdeZGdnq2nTpqmgoCBlb2+vWrRooe644w714YcfqoKCAqXUX6M9P/jgA/WPf/xD+fn5Ka1Wq/r27VvuiNyNGzeq3r17K0dHR+Xm5qbuuecedfjw4TLtrved3Ojv43pOnDihHnzwQdWmTRvl4OCgnJycVI8ePdS8efPKjJQWN06jVDX26YUQohIXLlxAp9Mxffp03nzzzTLzp06dyrfffsvx48fRarUWrTslJYWAgAA++OAD896lEJaSc35CiJtu0aJFFBcX8+STT5Y7f8uWLbz55psWB58QN4uc8xNC3DSbN2/m8OHDvPPOO0RERJhHXl5r9+7dtVuYENeQ8BNC3DRvv/02O3bsoHfv3nzyySfWLkeICsk5PyGEEI2OnPMTQgjR6Ej4CSGEaHQaxDk/k8lEamoqrq6uFj1nTgghRMOilCI7OxtfX19sbCrev2sQ4ZeamnpT7s8ohBCiYTh9+jStWrWqcL5F4Td37lzmzp1rvkdi586dmT59uvleeleejH21CRMmMG/evArXqZTirbfe4vPPPycrK4vevXszd+7cch9XUpErj0o5ffr0TblPoxBCiPrJYDDg5+d33UdoWRR+rVq14r333qNd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\n",
      "text/plain": [
       "<Figure size 500x300 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "plt.figure(figsize=(5,3))\n",
    "plt.plot(np.arange(1,epochs+1), lossv)\n",
    "plt.title('validation loss,epoch=%s'%epochs)\n",
    "\n",
    "plt.figure(figsize=(5,3))\n",
    "plt.plot(np.arange(1,epochs+1), accv)\n",
    "plt.title('validation accuracy,epoch=%s'%epochs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "909e084f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
